package com.poetize.plus.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.poetize.plus.entity.dto.SortDTO;
import com.poetize.plus.entity.dto.page.SortPageDTO;
import com.poetize.plus.entity.po.Label;
import com.poetize.plus.entity.po.Sort;
import com.poetize.plus.entity.vo.SelectVO;
import com.poetize.plus.entity.vo.SortVO;
import com.poetize.plus.entity.vo.page.SortPageVO;
import com.poetize.plus.mapper.LabelMapper;
import com.poetize.plus.mapper.SortMapper;
import com.poetize.plus.service.SortService;
import com.poetize.plus.utils.BaseConstant;
import com.poetize.plus.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @Author zuosy
 * @Date 2024/3/30 16:16
 **/
@Service
@RequiredArgsConstructor
public class SortServiceImpl extends ServiceImpl<SortMapper, Sort> implements SortService {

    private final LabelMapper labelMapper;

    private final RedisUtil redisUtil;

    @Override
    public Page<SortPageVO> sortPage(SortPageDTO sortPageDTO) {
        Page<Sort> sortPage = lambdaQuery().page(Page.of(sortPageDTO.getCurrent(), sortPageDTO.getSize()));

        Page<SortPageVO> result = new Page<>();
        List<Sort> sortList = sortPage.getRecords();
        if (CollectionUtils.isEmpty(sortList)){
            return result;
        }
        result.setTotal(sortPage.getTotal());
        result.setRecords(SortPageVO.convertPageList(sortList));
        return result;
    }

    @Override
    public Boolean addSort(SortDTO sortDTO) {
        Sort checkSortName = lambdaQuery()
                .eq(Sort::getSortName, sortDTO.sortName())
                .one();
        if (Objects.nonNull(checkSortName)){
            throw new IllegalArgumentException("该分类已存在");
        }
        Sort sort = SortDTO.convertDTO(sortDTO);
        boolean insert = baseMapper.insert(sort) > 0;
        if (!insert){
            throw new IllegalArgumentException("数据异常");
        }
        redisUtil.setHomeRedis(BaseConstant.Redis.HOME_SORT, this::selectHomeSort);
        return true;
    }

    @Override
    public SortVO querySort(Long id) {
        Sort sort = baseMapper.selectById(id);
        return Optional.ofNullable(sort)
                .map(SortVO::convert)
                .orElseThrow(() -> new IllegalArgumentException("数据异常"));
    }

    @Override
    public Boolean updateSort(SortDTO sortDTO) {
        Sort checkSortName = lambdaQuery()
                .eq(Sort::getSortName, sortDTO.sortName())
                .ne(Sort::getSortId, sortDTO.sortId())
                .one();
        if (Objects.nonNull(checkSortName)){
            throw new IllegalArgumentException("该分类已存在");
        }
        Sort sort = SortDTO.convertDTO(sortDTO);
        boolean update = baseMapper.updateById(sort) > 0;
        if (!update){
            throw new IllegalArgumentException("数据异常");
        }
        redisUtil.setHomeRedis(BaseConstant.Redis.HOME_SORT, this::selectHomeSort);
        return true;
    }

    @Override
    public Boolean deleteSort(Long id) {
        Long labelCount = new LambdaQueryChainWrapper<>(labelMapper).eq(Label::getSortId, id).count();
        if (labelCount > 0){
            throw new IllegalArgumentException("存在标签信息，不可删除");
        }
        boolean delete = baseMapper.deleteById(id) > 0;
        if (!delete){
            throw new IllegalArgumentException("数据异常");
        }
        redisUtil.setHomeRedis(BaseConstant.Redis.HOME_SORT, this::selectHomeSort);
        return true;
    }

    @Override
    public List<SortVO> getHomeSort() {
        return redisUtil.getHomeRedis(BaseConstant.Redis.HOME_SORT, this::selectHomeSort);
    }

    @Override
    public List<SelectVO> sortSelect() {
        List<Sort> sortList = lambdaQuery().list();
        return SelectVO.convertSortSelect(sortList);
    }

    /**
     * 分类数据
     * @return
     */
    private List<SortVO> selectHomeSort(){
        List<Sort> sortList = lambdaQuery().list();
        return SortVO.convertList(sortList);
    }
}
